/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package TestPrincipal;

import analisis.IntraProceduralAnalysis;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Ignore;
import org.junit.Test;
import static org.junit.Assert.*;
import reticulado.PointsToGraph;
import soot.Body;
import soot.Local;
import soot.PhaseOptions;
import soot.Scene;
import soot.SootClass;
import soot.SootMethod;
import soot.jimple.toolkits.callgraph.CHATransformer;
import soot.options.Options;
import soot.toolkits.graph.BriefUnitGraph;
import soot.toolkits.graph.UnitGraph;

/**
 *
 * @author Santiago Avendaño
 */
public class testEj1 {

    private static SootClass c;
    private static final String campoF1 = "f1";
    private static final String campoF2 = "f2";
    private static Local variableptr;
    private static Local variablet;
    private static Local variablex;
    private static Local variabley;
    private static Local variablez;
    private static Local variablety;
    private static Local variabletz;
    private static Local variableh;

    public testEj1() {
    }

    @BeforeClass
    public static void setUpClass() throws Exception {
        Options.v().set_keep_line_number(true);
        PhaseOptions.v().setPhaseOption("jb", "use-original-names:true");
        c = Scene.v().loadClassAndSupport("CasosTestIntra.C");
        c.setApplicationClass();
    }

    @AfterClass
    public static void tearDownClass() throws Exception {
    }

    @Before
    public void setUp() {
    }

    @After
    public void tearDown() {
    }

    @Test
    //@Ignore
    public void test_m00() {
        SootMethod m = c.getMethodByName("m_00");
        Body b = m.retrieveActiveBody();
        setearVariables(b);
        UnitGraph g = new BriefUnitGraph(b);
        IntraProceduralAnalysis an = new IntraProceduralAnalysis(g, null, null, null, null);
        PointsToGraph res = an.getResult();
        System.out.println(res.toString());
        assertTrue("las variables 'x' y 'z' pueden ser alias", res.mayAlias(variablex, variablez));
    }

    @Test
    //@Ignore
    public void test_m01() {
        SootMethod m = c.getMethodByName("m_01");
        Body b = m.retrieveActiveBody();
        setearVariables(b);
        UnitGraph g = new BriefUnitGraph(b);
        IntraProceduralAnalysis an = new IntraProceduralAnalysis(g, null, null, null, null);
        PointsToGraph res = an.getResult();
        System.out.println(res.toString());
        assertTrue("las variables 'x' y 'z' pueden ser alias", res.mayAlias(variablex, variablez));
        assertTrue("las variables 'x.f1' y 'x' pueden ser alias", res.mayAlias(variablex, campoF1, variablex));
        assertTrue("el campo x.f2 no fue inicializado (x.f2==null)", res.isNull(variablex, campoF2) == PointsToGraph.RespuestaNulidad.ES_NULL);
    }

    @Test
    //@Ignore
    public void test_m02() {
        SootMethod m = c.getMethodByName("m_02");
        Body b = m.retrieveActiveBody();
        setearVariables(b);
        //imprimirLocales(b);
        UnitGraph g = new BriefUnitGraph(b);
        IntraProceduralAnalysis an = new IntraProceduralAnalysis(g, null, null, null, null);
        PointsToGraph res = an.getResult();
        System.out.println(res.toString());

        assertFalse("las variables 'x' y 'y' pueden ser alias", res.mayAlias(variablex, variabley));
        assertTrue("las variables 'x.f1' y 'y' pueden ser alias", res.mayAlias(variablex, campoF1, variabley));
    }

    @Test
    //@Ignore
    public void test_m03() {
        SootMethod m = c.getMethodByName("m_03");
        Body b = m.retrieveActiveBody();
        setearVariables(b);
        UnitGraph g = new BriefUnitGraph(b);
        IntraProceduralAnalysis an = new IntraProceduralAnalysis(g, null, null, null, null);
        PointsToGraph res = an.getResult();
        System.out.println(res.toString());
        assertFalse("las variables 'x' y 'y' pueden ser alias", res.mayAlias(variablex, variabley));
        assertTrue("las variables 'y.f1' y 'y' pueden ser alias", res.mayAlias(variabley, campoF1, variabley));
    }

    @Test
    //@Ignore
    public void test_m04() {
        SootMethod m = c.getMethodByName("m_04");
        Body b = m.retrieveActiveBody();
        setearVariables(b);
        UnitGraph g = new BriefUnitGraph(b);
        IntraProceduralAnalysis an = new IntraProceduralAnalysis(g, null, null, null, null);
        PointsToGraph res = an.getResult();
        System.out.println(res.toString());
        assertTrue("las variables 't' y 'y' pueden ser alias", res.mayAlias(variablet, variabley));
        assertFalse("las variables 't' y 'x' pueden ser alias", res.mayAlias(variablet, variablex));
    }

    @Test
    //@Ignore
    public void test_m05() {
        SootMethod m = c.getMethodByName("m_05");
        Body b = m.retrieveActiveBody();
        setearVariables(b);
        UnitGraph g = new BriefUnitGraph(b);
        IntraProceduralAnalysis an = new IntraProceduralAnalysis(g, null, null, null, null);
        PointsToGraph res = an.getResult();
        System.out.println(res.toString());
        assertFalse("las variables 'x.f1' y 'x' pueden ser alias", res.mayAlias(variablex, campoF1, variablex));
        assertTrue("las variables 'x.f1' y 'y' pueden ser alias", res.mayAlias(variablex, campoF1, variabley));
        assertTrue("las variables 'x.f1' y 'z' pueden ser alias", res.mayAlias(variablex, campoF1, variablez));
    }

    @Test
    //@Ignore
    public void test_m06() {
        SootMethod m = c.getMethodByName("m_06");
        Body b = m.retrieveActiveBody();
        setearVariables(b);
        UnitGraph g = new BriefUnitGraph(b);
        IntraProceduralAnalysis an = new IntraProceduralAnalysis(g, null, null, null, null);
        PointsToGraph res = an.getResult();
        System.out.println(res.toString());

        assertTrue("el campo x no es null", res.isNull(variablex) == PointsToGraph.RespuestaNulidad.NO_ES_NULL);
        //assertTrue("x.f1 maybe null? SI", res.isNull(variablex,campoF1)== PointsToGraph.RespuestaNulidad.PUEDE_SER_NULL);
        //assertTrue("t.f1 maybe null? SI", res.isNull(variablet,campoF1)== PointsToGraph.RespuestaNulidad.PUEDE_SER_NULL);
        //assertTrue("t.f1 maybe not-null? SI", res.isNull(variablet,campoF1) != PointsToGraph.RespuestaNulidad.ES_NULL);
    }

    @Test
    @Ignore
    public void test_m07() {
        SootMethod m = c.getMethodByName("m_07");
        Body b = m.retrieveActiveBody();
        setearVariables(b);
        UnitGraph g = new BriefUnitGraph(b);
        IntraProceduralAnalysis an = new IntraProceduralAnalysis(g, null, null, null, null);
        PointsToGraph res = an.getResult();
        System.out.println(res.toString());

        assertFalse("x.f1 == null? NO", res.isNull(variablex, campoF1) == PointsToGraph.RespuestaNulidad.ES_NULL);
        assertFalse("x.f1 != null? NO", res.isNull(variablex, campoF1) == PointsToGraph.RespuestaNulidad.NO_ES_NULL);
        assertTrue("x.f1 maybe null", res.isNull(variablex, campoF1) == PointsToGraph.RespuestaNulidad.PUEDE_SER_NULL);
        assertTrue("x.f1 maybe not-null? SI", res.isNull(variablex, campoF1) != PointsToGraph.RespuestaNulidad.ES_NULL);
    }

    @Test
    //@Ignore
    public void test_m08() {
        SootMethod m = c.getMethodByName("m_08");
        Body b = m.retrieveActiveBody();
        setearVariables(b);
        UnitGraph g = new BriefUnitGraph(b);
        IntraProceduralAnalysis an = new IntraProceduralAnalysis(g, null, null, null, null);
        PointsToGraph res = an.getResult();
        System.out.println(res.toString());

        assertTrue("x == null? SI", res.isNull(variablex) == PointsToGraph.RespuestaNulidad.ES_NULL);

    }

    @Test
    //@Ignore
    public void test_m10() {
        SootMethod m = c.getMethodByName("m_10");
        Body b = m.retrieveActiveBody();
        setearVariables(b);
        UnitGraph g = new BriefUnitGraph(b);
        IntraProceduralAnalysis an = new IntraProceduralAnalysis(g, null, null, null, null);
        PointsToGraph res = an.getResult();
        System.out.println(res.toString());

        assertFalse("W is empty? NO", res.getProblemas().isEmpty());
    }

    @Test
    //@Ignore
    public void test_m12() {
        SootMethod m = c.getMethodByName("m_12");
        Body b = m.retrieveActiveBody();
        setearVariables(b);
        UnitGraph g = new BriefUnitGraph(b);
        IntraProceduralAnalysis an = new IntraProceduralAnalysis(g, null, null, null, null);
        PointsToGraph res = an.getResult();
        System.out.println(res.toString());

        assertTrue("t_y may-alias y? SI", res.mayAlias(variablety, variabley));
        assertFalse("t_z may-alias y? NO", res.mayAlias(variabletz, variabley));
    }

    @Test
    //@Ignore
    public void test_m13() {
        SootMethod m = c.getMethodByName("m_13");
        Body b = m.retrieveActiveBody();
        setearVariables(b);
        UnitGraph g = new BriefUnitGraph(b);
        IntraProceduralAnalysis an = new IntraProceduralAnalysis(g, null, null, null, null);
        PointsToGraph res = an.getResult();
        System.out.println(res.toString());

        assertTrue("y.f2 may-alias x ? SI", res.mayAlias(variabley, campoF2, variablex));
        assertFalse("z.f2 may-alias x ? SI", res.mayAlias(variabletz, campoF2, variablex));
    }

    @Test
    //@Ignore
    public void test_m14() {
        SootMethod m = c.getMethodByName("m_14");
        Body b = m.retrieveActiveBody();
        setearVariables(b);
        UnitGraph g = new BriefUnitGraph(b);
        IntraProceduralAnalysis an = new IntraProceduralAnalysis(g, null, null, null, null);
        PointsToGraph res = an.getResult();
        System.out.println(res.toString());

        assertTrue("y.f1 may-alias h ? SI", res.mayAlias(variabley, campoF1, variableh));
        assertTrue("z.f1 may-alias h ? SI", res.mayAlias(variablez, campoF1, variableh));
        assertFalse("h may-alias x ? NO", res.mayAlias(variableh, variablex));
    }

    private void setearVariables(Body b) {
        for (Local v : b.getLocals()) {
            if (v.getName().equals("ptr")) {
                variableptr = v;
            }
            if (v.getName().equals("t")) {
                variablet = v;
            }
            if (v.getName().equals("x")) {
                variablex = v;
            }
            if (v.getName().equals("y")) {
                variabley = v;
            }
            if (v.getName().equals("z")) {
                variablez = v;
            }
            if (v.getName().equals("t_y")) {
                variablety = v;
            }
            if (v.getName().equals("t_z")) {
                variabletz = v;
            }
            if (v.getName().equals("h")) {
                variableh = v;
            }

        }
    }

    private void imprimirLocales(Body b) {
        System.out.print("\n Variables locales: ");
        for (Local v : b.getLocals()) {
            System.out.print(v.getName() + " ");
        }
        System.out.print("\n");
    }
}
